#pragma once
#include "base/core/singleton.h"
#include "Common/ServerDefine.h"
#include "Common/NetPack/NetPack.h"
#include "Common/Utility/Service.h"
#include "Common/MessageDispatch/MessageDispatch.h"
#include "base/core/lua_parser.h"
#include "Common/Utility/JsonUtility.h"

class ZoneService : public Service, public ManualSingleton<ZoneService>
{
	friend class ManualSingleton<ZoneService>;
	typedef std::unordered_map<uint32_t, ISession*>  SESSION_MAP;
	typedef unordered_map<uint32_t, ISession*> UNCHECK_CLIENT_SESSIONMAP;

protected:
	uint16_t       m_listenPort;
	char           m_listenIp[ADDRESS_IP_LENGTH];
	void*          m_listenHandle;

	uint16_t       m_clientPort;
	char           m_clientListenIp[ADDRESS_IP_LENGTH];
	void*          m_clientListenHandle;

	GServerZoneInfo m_zone;

	uint64_t          m_syncStateTick;
	IMessageDispatch *m_pMessageDispatch;

	ServiceConnect    m_logServer;
	ServiceConnect    m_masterServer;

	SESSION_MAP   m_logicSessionMap;
	SESSION_MAP   m_gateSessionMap;

	ISession*     m_pCenterSession;

	uint64_t      m_openTime;
	bool          m_tokenCheck;

public:
	virtual bool Init(Net* net, const char* configFile)override;
	virtual void UnInit()override;
	virtual bool Update(uint64_t tick)override;
	virtual bool Quit() override;
	virtual bool HandleConsoleCmd(const char* cmd)override;
	virtual bool TrueClientMessage(RECV_PACKAGE& package);
	virtual IMessageDispatch *GetServiceMessageDispatch() override;

	bool AddGateSession(uint32_t gateId, ISession* pSession);

	bool _CheckQuittingComplete();

	bool SendDataToMaster(uint16_t module, uint16_t cmd, ProtoBufBase* data);
	bool SendDataToMaster(const char* data, uint32_t len);
	bool SendDataToAllGate(uint16_t module, uint16_t cmd);
	bool SendLogToLogServer(JsonObject& json);

	uint32_t GetZoneId() { return m_zone.zid; }
	uint64_t GetGameOpenTime() { return m_openTime; }
	bool TokenTimeCheck(){ return m_tokenCheck; }

protected:
	bool _LoadConfig(const char* config_file);
	bool _LoadZoneConfig(LuaRef& zoneConfig);
	bool _ListenAddress();
	bool _ListenClientAddress();

	bool _Register2Master();

	bool _ProcessConnection();
	bool _SyncServiceState();

	static bool _OnAcceptServer(ISession* session, void* context);
	static bool _OnCloseServer(ISession* session, void* context, CloseFlag flag);

	static bool _OnAcceptClient(ISession* session, void* context);
	static bool _OnCloseClient(ISession* session, void* context, CloseFlag flag);

	static bool _OnConnectMasterServer(ISession* session, void* context, bool success);
	static bool _OnConnectLogServer(ISession* session, void* context, bool success);

	ZoneService();
	virtual ~ZoneService()override;
};

#define g_MakeZoneService() (ZoneService::Instance())
#define g_GetZoneService()  (ZoneService::GetInstance())
#define g_DelZoneService()  (ZoneService::Destroy())
